package com.vecspace.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.vecspace.exception.HException;

/**条件过滤器（只能进行很有限的条件过滤） 
 * 只能识别有限的几种符号,包括: = like and in > < >= <= <>，其中like的通配符为*而不是%，in操作符的值域为逗号隔开的值（同时每个值不能含有逗号，引号）
 * @author: wanghua
 */
public class SimpleDataFilter {
	//private String filter;
	private List<String[]> filterList = new ArrayList<>();
	
	public SimpleDataFilter(){
		
	}
	
	public SimpleDataFilter(String filter) throws HException{
		setFilter(filter);
	}
	
	/**设置过滤条件
	 * @param filter 过滤条件。只能识别有限的几种符号,包括: = like and in > < >= <=，其中like的通配符为*而不是%，in操作符的值域为逗号隔开的值（同时每个值不能含有逗号，引号）
	 * @throws HException
	 * @author: wanghua
	 */
	public void setFilter(String filter) throws HException{
		//this.filter = filter;
		if(filter == null || filter.trim().length() == 0) {
			return;
		}
		filter = filter.trim();
		String[] filterArr = filter.split(" AND | and ");
		for(String filter1 : filterArr){
			String[] filterItem = new String[3];
			if(filter1.indexOf("=") > 0){
				int idx = filter1.indexOf("=");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 1);
				if(value.startsWith("'")) {
					value = value.substring(1);
				}
				if(value.endsWith("'")) {
					value = value.substring(0, value.length()-1).trim();
				}
				filterItem[0] = fieldName;
				filterItem[1] = "=";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf("<>") > 0){
				int idx = filter1.indexOf("<>");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 2);
				if(value.startsWith("'")) {
					value = value.substring(1);
				}
				if(value.endsWith("'")) {
					value = value.substring(0, value.length()-1).trim();
				}
				filterItem[0] = fieldName;
				filterItem[1] = "<>";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf("!=") > 0){
				int idx = filter1.indexOf("!=");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 2);
				if(value.startsWith("'")) {
					value = value.substring(1);
				}
				if(value.endsWith("'")) {
					value = value.substring(0, value.length()-1).trim();
				}
				filterItem[0] = fieldName;
				filterItem[1] = "!=";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf(" LIKE ") > 0 || filter1.indexOf(" like ") > 0){
				int idx = filter1.indexOf(" LIKE ");
				if(idx < 0) {
					idx = filter1.indexOf(" like ");
				}
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 6).trim();
				if(value.startsWith("'")) {
					value = value.substring(1);
				}
				if(value.endsWith("'")) {
					value = value.substring(0, value.length()-1);
				}
				
				String op = "like";
				if(value.startsWith("*") && !value.endsWith("*")) {
					op = "llike";
				}
				else if(!value.startsWith("*") && value.endsWith("*")) {
					op = "rlike";
				}
				
				if(value.startsWith("*")) {
					value = value.substring(1);
				}
				if(value.endsWith("*")) {
					value = value.substring(0, value.length()-1);
				}
				
				filterItem[0] = fieldName;
				filterItem[1] = op;
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf(" IN ") > 0 || filter1.indexOf(" in ") > 0){
				int idx = filter1.indexOf(" IN ");
				if(idx < 0) {
					idx = filter1.indexOf(" in ");
				}
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 4);
				if(value.startsWith("(")) {
					value = value.substring(1);
				}
				if(value.endsWith(")")) {
					value = value.substring(0, value.length()-1);
				}
				value=","+value+",";
				value = value.replace(" ", "");
				value = value.replace("'", "");// value格式，以逗号分隔的字符串:  ,12,24,abc,xyz,aaa,bbbcc,wwww,ssss,	
				
				filterItem[0] = fieldName;
				filterItem[1] = "in";
				filterItem[2] = value;//每一个值里面不能有逗号、空格
				filterList.add(filterItem);	
			}else if(filter1.indexOf(">") > 0){
				int idx = filter1.indexOf(">");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 1).trim();
				Double.parseDouble(value);//如果无法转换，抛出异常
				filterItem[0] = fieldName;
				filterItem[1] = ">";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf("<") > 0){
				int idx = filter1.indexOf("<");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 1).trim();
				Double.parseDouble(value);//如果无法转换，抛出异常
				filterItem[0] = fieldName;
				filterItem[1] = "<";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf(">=") > 0){
				int idx = filter1.indexOf(">=");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 2).trim();
				Double.parseDouble(value);//如果无法转换，抛出异常
				filterItem[0] = fieldName;
				filterItem[1] = ">=";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else if(filter1.indexOf("<=") > 0){
				int idx = filter1.indexOf("<=");
				String fieldName = filter1.substring(0, idx).trim();
				String value = filter1.substring(idx + 2).trim();
				Double.parseDouble(value);//如果无法转换，抛出异常
				filterItem[0] = fieldName;
				filterItem[1] = "<=";
				filterItem[2] = value;
				filterList.add(filterItem);
			}else {
				throw new HException("不能识别的操作符");
			}
		}
	}
	
	/**
	 * 检测row是否满足过滤条件。满足过滤条件则返回true，否则返回false
	 * 如果过滤条件为空，则统一返回true
	 * @param row
	 * @return
	 * @author: wanghua
	 */
	public boolean test(Map<String, Object> row){
		if(row == null) {
			return false;
		}
		if(filterList.size() == 0) {
			return true;
		}
		boolean eq = true;
		for(String[] filterItem : filterList){			
			String sqlOp = filterItem[1];
			String sqlValue = filterItem[2];
			if("=".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(!value.equals(sqlValue)){
					eq = false;
				}
			}else if("<>".equals(sqlOp) || "!=".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(value.equals(sqlValue)){
					eq = false;
				}
			}else if(">".equals(sqlOp)){
				Double value = Convert.toDouble(row.get(filterItem[0]), 0);
				Double sqlValueNum = Convert.toDouble(sqlValue, Double.MAX_VALUE);
				if(value <= sqlValueNum){
					eq = false;
				}
			}else if(">=".equals(sqlOp)){
				Double value = Convert.toDouble(row.get(filterItem[0]), 0);
				Double sqlValueNum = Convert.toDouble(sqlValue, Double.MAX_VALUE);
				if(value <= sqlValueNum){
					eq = false;
				}
			}else if("<".equals(sqlOp)){
				Double value = Convert.toDouble(row.get(filterItem[0]), 0);
				Double sqlValueNum = Convert.toDouble(sqlValue, Double.MAX_VALUE);
				if(value >= sqlValueNum){
					eq = false;
				}
			}else if("<=".equals(sqlOp)){
				Double value = Convert.toDouble(row.get(filterItem[0]), 0);
				Double sqlValueNum = Convert.toDouble(sqlValue, Double.MAX_VALUE);
				if(value > sqlValueNum){
					eq = false;
				}
			}else if("rlike".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(!value.startsWith(sqlValue)){
					eq = false;
				}
			}else if("llike".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(!value.endsWith(sqlValue)){
					eq = false;
				}
			}else if("like".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(!value.contains(sqlValue)){
					eq = false;
				}
			}else if("in".equals(sqlOp)){
				String value = Convert.toString(row.get(filterItem[0]), "");
				if(!sqlValue.contains(","+value+",")){
					eq = false;
				}
			}else {
				eq = false;
			}
		}
		return eq;
	}
}
